1 /*
2 * Copyright (C) 2007 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static com.google.common.collect.CollectPreconditions.checkNonnegative;
21 import static com.google.common.collect.CollectPreconditions.checkRemove;
22
23 import com.google.common.annotations.Beta;
24 import com.google.common.annotations.GwtCompatible;
25 import com.google.common.base.Function;
26 import com.google.common.base.Predicate;
27 import com.google.common.base.Predicates;
28 import com.google.common.base.Supplier;
29 import com.google.common.collect.Maps.EntryTransformer;
30
31 import java.io.Serializable;
32 import java.util.AbstractCollection;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.Comparator;
36 import java.util.HashSet;
37 import java.util.Iterator;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Map.Entry;
41 import java.util.NoSuchElementException;
42 import java.util.Set;
43 import java.util.SortedSet;
44
45 import javax.annotation.Nullable;
46
47 /**
48 * Provides static methods acting on or generating a {@code Multimap}.
49 *
50 * <p>See the Guava User Guide article on <a href=
51 * "http://code.google.com/p/guava-libraries/wiki/CollectionUtilitiesExplained#Multimaps">
52 * {@code Multimaps}</a>.
53 *
54 * @author Jared Levy
55 * @author Robert Konigsberg
56 * @author Mike Bostock
57 * @author Louis Wasserman
58 * @since 2.0 (imported from Google Collections Library)
59 */
60 @GwtCompatible(emulated = true)
61 public final class Multimaps {
62 private Multimaps() {}
63
64 /**
65 * Creates a new {@code Multimap} backed by {@code map}, whose internal value
66 * collections are generated by {@code factory}.
67 *
68 * <b>Warning: do not use</b> this method when the collections returned by
69 * {@code factory} implement either {@link List} or {@code Set}! Use the more
70 * specific method {@link #newListMultimap}, {@link #newSetMultimap} or {@link
71 * #newSortedSetMultimap} instead, to avoid very surprising behavior from
72 * {@link Multimap#equals}.
73 *
74 * <p>The {@code factory}-generated and {@code map} classes determine the
75 * multimap iteration order. They also specify the behavior of the
76 * {@code equals}, {@code hashCode}, and {@code toString} methods for the
77 * multimap and its returned views. However, the multimap's {@code get}
78 * method returns instances of a different class than {@code factory.get()}
79 * does.
80 *
81 * <p>The multimap is serializable if {@code map}, {@code factory}, the
82 * collections generated by {@code factory}, and the multimap contents are all
83 * serializable.
84 *
85 * <p>The multimap is not threadsafe when any concurrent operations update the
86 * multimap, even if {@code map} and the instances generated by
87 * {@code factory} are. Concurrent read operations will work correctly. To
88 * allow concurrent update operations, wrap the multimap with a call to
89 * {@link #synchronizedMultimap}.
90 *
91 * <p>Call this method only when the simpler methods
92 * {@link ArrayListMultimap#create()}, {@link HashMultimap#create()},
93 * {@link LinkedHashMultimap#create()}, {@link LinkedListMultimap#create()},
94 * {@link TreeMultimap#create()}, and
95 * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
96 *
97 * <p>Note: the multimap assumes complete ownership over of {@code map} and
98 * the collections returned by {@code factory}. Those objects should not be
99 * manually updated and they should not use soft, weak, or phantom references.
100 *
101 * @param map place to store the mapping from each key to its corresponding
102 * values
103 * @param factory supplier of new, empty collections that will each hold all
104 * values for a given key
105 * @throws IllegalArgumentException if {@code map} is not empty
106 */
107 public static <K, V> Multimap<K, V> newMultimap(Map<K, Collection<V>> map,
108 final Supplier<? extends Collection<V>> factory) {
109 return new CustomMultimap<K, V>(map, factory);
110 }
111
112 private static class CustomMultimap<K, V> extends AbstractMapBasedMultimap<K, V> {
113 transient Supplier<? extends Collection<V>> factory;
114
115 CustomMultimap(Map<K, Collection<V>> map,
116 Supplier<? extends Collection<V>> factory) {
117 super(map);
118 this.factory = checkNotNull(factory);
119 }
120
121 @Override protected Collection<V> createCollection() {
122 return factory.get();
123 }
124
125 // can't use Serialization writeMultimap and populateMultimap methods since
126 // there's no way to generate the empty backing map.
127 }
128
129 /**
130 * Creates a new {@code ListMultimap} that uses the provided map and factory.
131 * It can generate a multimap based on arbitrary {@link Map} and {@link List}
132 * classes.
133 *
134 * <p>The {@code factory}-generated and {@code map} classes determine the
135 * multimap iteration order. They also specify the behavior of the
136 * {@code equals}, {@code hashCode}, and {@code toString} methods for the
137 * multimap and its returned views. The multimap's {@code get}, {@code
138 * removeAll}, and {@code replaceValues} methods return {@code RandomAccess}
139 * lists if the factory does. However, the multimap's {@code get} method
140 * returns instances of a different class than does {@code factory.get()}.
141 *
142 * <p>The multimap is serializable if {@code map}, {@code factory}, the
143 * lists generated by {@code factory}, and the multimap contents are all
144 * serializable.
145 *
146 * <p>The multimap is not threadsafe when any concurrent operations update the
147 * multimap, even if {@code map} and the instances generated by
148 * {@code factory} are. Concurrent read operations will work correctly. To
149 * allow concurrent update operations, wrap the multimap with a call to
150 * {@link #synchronizedListMultimap}.
151 *
152 * <p>Call this method only when the simpler methods
153 * {@link ArrayListMultimap#create()} and {@link LinkedListMultimap#create()}
154 * won't suffice.
155 *
156 * <p>Note: the multimap assumes complete ownership over of {@code map} and
157 * the lists returned by {@code factory}. Those objects should not be manually
158 * updated, they should be empty when provided, and they should not use soft,
159 * weak, or phantom references.
160 *
161 * @param map place to store the mapping from each key to its corresponding
162 * values
163 * @param factory supplier of new, empty lists that will each hold all values
164 * for a given key
165 * @throws IllegalArgumentException if {@code map} is not empty
166 */
167 public static <K, V> ListMultimap<K, V> newListMultimap(
168 Map<K, Collection<V>> map, final Supplier<? extends List<V>> factory) {
169 return new CustomListMultimap<K, V>(map, factory);
170 }
171
172 private static class CustomListMultimap<K, V>
173 extends AbstractListMultimap<K, V> {
174 transient Supplier<? extends List<V>> factory;
175
176 CustomListMultimap(Map<K, Collection<V>> map,
177 Supplier<? extends List<V>> factory) {
178 super(map);
179 this.factory = checkNotNull(factory);
180 }
181
182 @Override protected List<V> createCollection() {
183 return factory.get();
184 }
185 }
186
187 /**
188 * Creates a new {@code SetMultimap} that uses the provided map and factory.
189 * It can generate a multimap based on arbitrary {@link Map} and {@link Set}
190 * classes.
191 *
192 * <p>The {@code factory}-generated and {@code map} classes determine the
193 * multimap iteration order. They also specify the behavior of the
194 * {@code equals}, {@code hashCode}, and {@code toString} methods for the
195 * multimap and its returned views. However, the multimap's {@code get}
196 * method returns instances of a different class than {@code factory.get()}
197 * does.
198 *
199 * <p>The multimap is serializable if {@code map}, {@code factory}, the
200 * sets generated by {@code factory}, and the multimap contents are all
201 * serializable.
202 *
203 * <p>The multimap is not threadsafe when any concurrent operations update the
204 * multimap, even if {@code map} and the instances generated by
205 * {@code factory} are. Concurrent read operations will work correctly. To
206 * allow concurrent update operations, wrap the multimap with a call to
207 * {@link #synchronizedSetMultimap}.
208 *
209 * <p>Call this method only when the simpler methods
210 * {@link HashMultimap#create()}, {@link LinkedHashMultimap#create()},
211 * {@link TreeMultimap#create()}, and
212 * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
213 *
214 * <p>Note: the multimap assumes complete ownership over of {@code map} and
215 * the sets returned by {@code factory}. Those objects should not be manually
216 * updated and they should not use soft, weak, or phantom references.
217 *
218 * @param map place to store the mapping from each key to its corresponding
219 * values
220 * @param factory supplier of new, empty sets that will each hold all values
221 * for a given key
222 * @throws IllegalArgumentException if {@code map} is not empty
223 */
224 public static <K, V> SetMultimap<K, V> newSetMultimap(
225 Map<K, Collection<V>> map, final Supplier<? extends Set<V>> factory) {
226 return new CustomSetMultimap<K, V>(map, factory);
227 }
228
229 private static class CustomSetMultimap<K, V>
230 extends AbstractSetMultimap<K, V> {
231 transient Supplier<? extends Set<V>> factory;
232
233 CustomSetMultimap(Map<K, Collection<V>> map,
234 Supplier<? extends Set<V>> factory) {
235 super(map);
236 this.factory = checkNotNull(factory);
237 }
238
239 @Override protected Set<V> createCollection() {
240 return factory.get();
241 }
242 }
243
244 /**
245 * Creates a new {@code SortedSetMultimap} that uses the provided map and
246 * factory. It can generate a multimap based on arbitrary {@link Map} and
247 * {@link SortedSet} classes.
248 *
249 * <p>The {@code factory}-generated and {@code map} classes determine the
250 * multimap iteration order. They also specify the behavior of the
251 * {@code equals}, {@code hashCode}, and {@code toString} methods for the
252 * multimap and its returned views. However, the multimap's {@code get}
253 * method returns instances of a different class than {@code factory.get()}
254 * does.
255 *
256 * <p>The multimap is serializable if {@code map}, {@code factory}, the
257 * sets generated by {@code factory}, and the multimap contents are all
258 * serializable.
259 *
260 * <p>The multimap is not threadsafe when any concurrent operations update the
261 * multimap, even if {@code map} and the instances generated by
262 * {@code factory} are. Concurrent read operations will work correctly. To
263 * allow concurrent update operations, wrap the multimap with a call to
264 * {@link #synchronizedSortedSetMultimap}.
265 *
266 * <p>Call this method only when the simpler methods
267 * {@link TreeMultimap#create()} and
268 * {@link TreeMultimap#create(Comparator, Comparator)} won't suffice.
269 *
270 * <p>Note: the multimap assumes complete ownership over of {@code map} and
271 * the sets returned by {@code factory}. Those objects should not be manually
272 * updated and they should not use soft, weak, or phantom references.
273 *
274 * @param map place to store the mapping from each key to its corresponding
275 * values
276 * @param factory supplier of new, empty sorted sets that will each hold
277 * all values for a given key
278 * @throws IllegalArgumentException if {@code map} is not empty
279 */
280 public static <K, V> SortedSetMultimap<K, V> newSortedSetMultimap(
281 Map<K, Collection<V>> map,
282 final Supplier<? extends SortedSet<V>> factory) {
283 return new CustomSortedSetMultimap<K, V>(map, factory);
284 }
285
286 private static class CustomSortedSetMultimap<K, V>
287 extends AbstractSortedSetMultimap<K, V> {
288 transient Supplier<? extends SortedSet<V>> factory;
289 transient Comparator<? super V> valueComparator;
290
291 CustomSortedSetMultimap(Map<K, Collection<V>> map,
292 Supplier<? extends SortedSet<V>> factory) {
293 super(map);
294 this.factory = checkNotNull(factory);
295 valueComparator = factory.get().comparator();
296 }
297
298 @Override protected SortedSet<V> createCollection() {
299 return factory.get();
300 }
301
302 @Override public Comparator<? super V> valueComparator() {
303 return valueComparator;
304 }
305 }
306
307 /**
308 * Copies each key-value mapping in {@code source} into {@code dest}, with
309 * its key and value reversed.
310 *
311 * <p>If {@code source} is an {@link ImmutableMultimap}, consider using
312 * {@link ImmutableMultimap#inverse} instead.
313 *
314 * @param source any multimap
315 * @param dest the multimap to copy into; usually empty
316 * @return {@code dest}
317 */
318 public static <K, V, M extends Multimap<K, V>> M invertFrom(
319 Multimap<? extends V, ? extends K> source, M dest) {
320 checkNotNull(dest);
321 for (Map.Entry<? extends V, ? extends K> entry : source.entries()) {
322 dest.put(entry.getValue(), entry.getKey());
323 }
324 return dest;
325 }
326
327 /**
328 * Returns a synchronized (thread-safe) multimap backed by the specified
329 * multimap. In order to guarantee serial access, it is critical that
330 * <b>all</b> access to the backing multimap is accomplished through the
331 * returned multimap.
332 *
333 * <p>It is imperative that the user manually synchronize on the returned
334 * multimap when accessing any of its collection views: <pre> {@code
335 *
336 * Multimap<K, V> multimap = Multimaps.synchronizedMultimap(
337 * HashMultimap.<K, V>create());
338 * ...
339 * Collection<V> values = multimap.get(key); // Needn't be in synchronized block
340 * ...
341 * synchronized (multimap) { // Synchronizing on multimap, not values!
342 * Iterator<V> i = values.iterator(); // Must be in synchronized block
343 * while (i.hasNext()) {
344 * foo(i.next());
345 * }
346 * }}</pre>
347 *
348 * <p>Failure to follow this advice may result in non-deterministic behavior.
349 *
350 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
351 * {@link Multimap#replaceValues} methods return collections that aren't
352 * synchronized.
353 *
354 * <p>The returned multimap will be serializable if the specified multimap is
355 * serializable.
356 *
357 * @param multimap the multimap to be wrapped in a synchronized view
358 * @return a synchronized view of the specified multimap
359 */
360 public static <K, V> Multimap<K, V> synchronizedMultimap(
361 Multimap<K, V> multimap) {
362 return Synchronized.multimap(multimap, null);
363 }
364
365 /**
366 * Returns an unmodifiable view of the specified multimap. Query operations on
367 * the returned multimap "read through" to the specified multimap, and
368 * attempts to modify the returned multimap, either directly or through the
369 * multimap's views, result in an {@code UnsupportedOperationException}.
370 *
371 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
372 * {@link Multimap#replaceValues} methods return collections that are
373 * modifiable.
374 *
375 * <p>The returned multimap will be serializable if the specified multimap is
376 * serializable.
377 *
378 * @param delegate the multimap for which an unmodifiable view is to be
379 * returned
380 * @return an unmodifiable view of the specified multimap
381 */
382 public static <K, V> Multimap<K, V> unmodifiableMultimap(
383 Multimap<K, V> delegate) {
384 if (delegate instanceof UnmodifiableMultimap ||
385 delegate instanceof ImmutableMultimap) {
386 return delegate;
387 }
388 return new UnmodifiableMultimap<K, V>(delegate);
389 }
390
391 /**
392 * Simply returns its argument.
393 *
394 * @deprecated no need to use this
395 * @since 10.0
396 */
397 @Deprecated public static <K, V> Multimap<K, V> unmodifiableMultimap(
398 ImmutableMultimap<K, V> delegate) {
399 return checkNotNull(delegate);
400 }
401
402 private static class UnmodifiableMultimap<K, V>
403 extends ForwardingMultimap<K, V> implements Serializable {
404 final Multimap<K, V> delegate;
405 transient Collection<Entry<K, V>> entries;
406 transient Multiset<K> keys;
407 transient Set<K> keySet;
408 transient Collection<V> values;
409 transient Map<K, Collection<V>> map;
410
411 UnmodifiableMultimap(final Multimap<K, V> delegate) {
412 this.delegate = checkNotNull(delegate);
413 }
414
415 @Override protected Multimap<K, V> delegate() {
416 return delegate;
417 }
418
419 @Override public void clear() {
420 throw new UnsupportedOperationException();
421 }
422
423 @Override public Map<K, Collection<V>> asMap() {
424 Map<K, Collection<V>> result = map;
425 if (result == null) {
426 result = map = Collections.unmodifiableMap(
427 Maps.transformValues(delegate.asMap(), new Function<Collection<V>, Collection<V>>() {
428 @Override
429 public Collection<V> apply(Collection<V> collection) {
430 return unmodifiableValueCollection(collection);
431 }
432 }));
433 }
434 return result;
435 }
436
437 @Override public Collection<Entry<K, V>> entries() {
438 Collection<Entry<K, V>> result = entries;
439 if (result == null) {
440 entries = result = unmodifiableEntries(delegate.entries());
441 }
442 return result;
443 }
444
445 @Override public Collection<V> get(K key) {
446 return unmodifiableValueCollection(delegate.get(key));
447 }
448
449 @Override public Multiset<K> keys() {
450 Multiset<K> result = keys;
451 if (result == null) {
452 keys = result = Multisets.unmodifiableMultiset(delegate.keys());
453 }
454 return result;
455 }
456
457 @Override public Set<K> keySet() {
458 Set<K> result = keySet;
459 if (result == null) {
460 keySet = result = Collections.unmodifiableSet(delegate.keySet());
461 }
462 return result;
463 }
464
465 @Override public boolean put(K key, V value) {
466 throw new UnsupportedOperationException();
467 }
468
469 @Override public boolean putAll(K key, Iterable<? extends V> values) {
470 throw new UnsupportedOperationException();
471 }
472
473 @Override
474 public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
475 throw new UnsupportedOperationException();
476 }
477
478 @Override public boolean remove(Object key, Object value) {
479 throw new UnsupportedOperationException();
480 }
481
482 @Override public Collection<V> removeAll(Object key) {
483 throw new UnsupportedOperationException();
484 }
485
486 @Override public Collection<V> replaceValues(
487 K key, Iterable<? extends V> values) {
488 throw new UnsupportedOperationException();
489 }
490
491 @Override public Collection<V> values() {
492 Collection<V> result = values;
493 if (result == null) {
494 values = result = Collections.unmodifiableCollection(delegate.values());
495 }
496 return result;
497 }
498
499 private static final long serialVersionUID = 0;
500 }
501
502 private static class UnmodifiableListMultimap<K, V>
503 extends UnmodifiableMultimap<K, V> implements ListMultimap<K, V> {
504 UnmodifiableListMultimap(ListMultimap<K, V> delegate) {
505 super(delegate);
506 }
507 @Override public ListMultimap<K, V> delegate() {
508 return (ListMultimap<K, V>) super.delegate();
509 }
510 @Override public List<V> get(K key) {
511 return Collections.unmodifiableList(delegate().get(key));
512 }
513 @Override public List<V> removeAll(Object key) {
514 throw new UnsupportedOperationException();
515 }
516 @Override public List<V> replaceValues(
517 K key, Iterable<? extends V> values) {
518 throw new UnsupportedOperationException();
519 }
520 private static final long serialVersionUID = 0;
521 }
522
523 private static class UnmodifiableSetMultimap<K, V>
524 extends UnmodifiableMultimap<K, V> implements SetMultimap<K, V> {
525 UnmodifiableSetMultimap(SetMultimap<K, V> delegate) {
526 super(delegate);
527 }
528 @Override public SetMultimap<K, V> delegate() {
529 return (SetMultimap<K, V>) super.delegate();
530 }
531 @Override public Set<V> get(K key) {
532 /*
533 * Note that this doesn't return a SortedSet when delegate is a
534 * SortedSetMultiset, unlike (SortedSet<V>) super.get().
535 */
536 return Collections.unmodifiableSet(delegate().get(key));
537 }
538 @Override public Set<Map.Entry<K, V>> entries() {
539 return Maps.unmodifiableEntrySet(delegate().entries());
540 }
541 @Override public Set<V> removeAll(Object key) {
542 throw new UnsupportedOperationException();
543 }
544 @Override public Set<V> replaceValues(
545 K key, Iterable<? extends V> values) {
546 throw new UnsupportedOperationException();
547 }
548 private static final long serialVersionUID = 0;
549 }
550
551 private static class UnmodifiableSortedSetMultimap<K, V>
552 extends UnmodifiableSetMultimap<K, V> implements SortedSetMultimap<K, V> {
553 UnmodifiableSortedSetMultimap(SortedSetMultimap<K, V> delegate) {
554 super(delegate);
555 }
556 @Override public SortedSetMultimap<K, V> delegate() {
557 return (SortedSetMultimap<K, V>) super.delegate();
558 }
559 @Override public SortedSet<V> get(K key) {
560 return Collections.unmodifiableSortedSet(delegate().get(key));
561 }
562 @Override public SortedSet<V> removeAll(Object key) {
563 throw new UnsupportedOperationException();
564 }
565 @Override public SortedSet<V> replaceValues(
566 K key, Iterable<? extends V> values) {
567 throw new UnsupportedOperationException();
568 }
569 @Override
570 public Comparator<? super V> valueComparator() {
571 return delegate().valueComparator();
572 }
573 private static final long serialVersionUID = 0;
574 }
575
576 /**
577 * Returns a synchronized (thread-safe) {@code SetMultimap} backed by the
578 * specified multimap.
579 *
580 * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
581 *
582 * <p>The returned multimap will be serializable if the specified multimap is
583 * serializable.
584 *
585 * @param multimap the multimap to be wrapped
586 * @return a synchronized view of the specified multimap
587 */
588 public static <K, V> SetMultimap<K, V> synchronizedSetMultimap(
589 SetMultimap<K, V> multimap) {
590 return Synchronized.setMultimap(multimap, null);
591 }
592
593 /**
594 * Returns an unmodifiable view of the specified {@code SetMultimap}. Query
595 * operations on the returned multimap "read through" to the specified
596 * multimap, and attempts to modify the returned multimap, either directly or
597 * through the multimap's views, result in an
598 * {@code UnsupportedOperationException}.
599 *
600 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
601 * {@link Multimap#replaceValues} methods return collections that are
602 * modifiable.
603 *
604 * <p>The returned multimap will be serializable if the specified multimap is
605 * serializable.
606 *
607 * @param delegate the multimap for which an unmodifiable view is to be
608 * returned
609 * @return an unmodifiable view of the specified multimap
610 */
611 public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
612 SetMultimap<K, V> delegate) {
613 if (delegate instanceof UnmodifiableSetMultimap ||
614 delegate instanceof ImmutableSetMultimap) {
615 return delegate;
616 }
617 return new UnmodifiableSetMultimap<K, V>(delegate);
618 }
619
620 /**
621 * Simply returns its argument.
622 *
623 * @deprecated no need to use this
624 * @since 10.0
625 */
626 @Deprecated public static <K, V> SetMultimap<K, V> unmodifiableSetMultimap(
627 ImmutableSetMultimap<K, V> delegate) {
628 return checkNotNull(delegate);
629 }
630
631 /**
632 * Returns a synchronized (thread-safe) {@code SortedSetMultimap} backed by
633 * the specified multimap.
634 *
635 * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
636 *
637 * <p>The returned multimap will be serializable if the specified multimap is
638 * serializable.
639 *
640 * @param multimap the multimap to be wrapped
641 * @return a synchronized view of the specified multimap
642 */
643 public static <K, V> SortedSetMultimap<K, V>
644 synchronizedSortedSetMultimap(SortedSetMultimap<K, V> multimap) {
645 return Synchronized.sortedSetMultimap(multimap, null);
646 }
647
648 /**
649 * Returns an unmodifiable view of the specified {@code SortedSetMultimap}.
650 * Query operations on the returned multimap "read through" to the specified
651 * multimap, and attempts to modify the returned multimap, either directly or
652 * through the multimap's views, result in an
653 * {@code UnsupportedOperationException}.
654 *
655 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
656 * {@link Multimap#replaceValues} methods return collections that are
657 * modifiable.
658 *
659 * <p>The returned multimap will be serializable if the specified multimap is
660 * serializable.
661 *
662 * @param delegate the multimap for which an unmodifiable view is to be
663 * returned
664 * @return an unmodifiable view of the specified multimap
665 */
666 public static <K, V> SortedSetMultimap<K, V> unmodifiableSortedSetMultimap(
667 SortedSetMultimap<K, V> delegate) {
668 if (delegate instanceof UnmodifiableSortedSetMultimap) {
669 return delegate;
670 }
671 return new UnmodifiableSortedSetMultimap<K, V>(delegate);
672 }
673
674 /**
675 * Returns a synchronized (thread-safe) {@code ListMultimap} backed by the
676 * specified multimap.
677 *
678 * <p>You must follow the warnings described in {@link #synchronizedMultimap}.
679 *
680 * @param multimap the multimap to be wrapped
681 * @return a synchronized view of the specified multimap
682 */
683 public static <K, V> ListMultimap<K, V> synchronizedListMultimap(
684 ListMultimap<K, V> multimap) {
685 return Synchronized.listMultimap(multimap, null);
686 }
687
688 /**
689 * Returns an unmodifiable view of the specified {@code ListMultimap}. Query
690 * operations on the returned multimap "read through" to the specified
691 * multimap, and attempts to modify the returned multimap, either directly or
692 * through the multimap's views, result in an
693 * {@code UnsupportedOperationException}.
694 *
695 * <p>Note that the generated multimap's {@link Multimap#removeAll} and
696 * {@link Multimap#replaceValues} methods return collections that are
697 * modifiable.
698 *
699 * <p>The returned multimap will be serializable if the specified multimap is
700 * serializable.
701 *
702 * @param delegate the multimap for which an unmodifiable view is to be
703 * returned
704 * @return an unmodifiable view of the specified multimap
705 */
706 public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
707 ListMultimap<K, V> delegate) {
708 if (delegate instanceof UnmodifiableListMultimap ||
709 delegate instanceof ImmutableListMultimap) {
710 return delegate;
711 }
712 return new UnmodifiableListMultimap<K, V>(delegate);
713 }
714
715 /**
716 * Simply returns its argument.
717 *
718 * @deprecated no need to use this
719 * @since 10.0
720 */
721 @Deprecated public static <K, V> ListMultimap<K, V> unmodifiableListMultimap(
722 ImmutableListMultimap<K, V> delegate) {
723 return checkNotNull(delegate);
724 }
725
726 /**
727 * Returns an unmodifiable view of the specified collection, preserving the
728 * interface for instances of {@code SortedSet}, {@code Set}, {@code List} and
729 * {@code Collection}, in that order of preference.
730 *
731 * @param collection the collection for which to return an unmodifiable view
732 * @return an unmodifiable view of the collection
733 */
734 private static <V> Collection<V> unmodifiableValueCollection(
735 Collection<V> collection) {
736 if (collection instanceof SortedSet) {
737 return Collections.unmodifiableSortedSet((SortedSet<V>) collection);
738 } else if (collection instanceof Set) {
739 return Collections.unmodifiableSet((Set<V>) collection);
740 } else if (collection instanceof List) {
741 return Collections.unmodifiableList((List<V>) collection);
742 }
743 return Collections.unmodifiableCollection(collection);
744 }
745
746 /**
747 * Returns an unmodifiable view of the specified collection of entries. The
748 * {@link Entry#setValue} operation throws an {@link
749 * UnsupportedOperationException}. If the specified collection is a {@code
750 * Set}, the returned collection is also a {@code Set}.
751 *
752 * @param entries the entries for which to return an unmodifiable view
753 * @return an unmodifiable view of the entries
754 */
755 private static <K, V> Collection<Entry<K, V>> unmodifiableEntries(
756 Collection<Entry<K, V>> entries) {
757 if (entries instanceof Set) {
758 return Maps.unmodifiableEntrySet((Set<Entry<K, V>>) entries);
759 }
760 return new Maps.UnmodifiableEntries<K, V>(
761 Collections.unmodifiableCollection(entries));
762 }
763
764 /**
765 * Returns {@link ListMultimap#asMap multimap.asMap()}, with its type
766 * corrected from {@code Map<K, Collection<V>>} to {@code Map<K, List<V>>}.
767 *
768 * @since 15.0
769 */
770 @Beta
771 @SuppressWarnings("unchecked")
772 // safe by specification of ListMultimap.asMap()
773 public static <K, V> Map<K, List<V>> asMap(ListMultimap<K, V> multimap) {
774 return (Map<K, List<V>>) (Map<K, ?>) multimap.asMap();
775 }
776
777 /**
778 * Returns {@link SetMultimap#asMap multimap.asMap()}, with its type corrected
779 * from {@code Map<K, Collection<V>>} to {@code Map<K, Set<V>>}.
780 *
781 * @since 15.0
782 */
783 @Beta
784 @SuppressWarnings("unchecked")
785 // safe by specification of SetMultimap.asMap()
786 public static <K, V> Map<K, Set<V>> asMap(SetMultimap<K, V> multimap) {
787 return (Map<K, Set<V>>) (Map<K, ?>) multimap.asMap();
788 }
789
790 /**
791 * Returns {@link SortedSetMultimap#asMap multimap.asMap()}, with its type
792 * corrected from {@code Map<K, Collection<V>>} to
793 * {@code Map<K, SortedSet<V>>}.
794 *
795 * @since 15.0
796 */
797 @Beta
798 @SuppressWarnings("unchecked")
799 // safe by specification of SortedSetMultimap.asMap()
800 public static <K, V> Map<K, SortedSet<V>> asMap(
801 SortedSetMultimap<K, V> multimap) {
802 return (Map<K, SortedSet<V>>) (Map<K, ?>) multimap.asMap();
803 }
804
805 /**
806 * Returns {@link Multimap#asMap multimap.asMap()}. This is provided for
807 * parity with the other more strongly-typed {@code asMap()} implementations.
808 *
809 * @since 15.0
810 */
811 @Beta
812 public static <K, V> Map<K, Collection<V>> asMap(Multimap<K, V> multimap) {
813 return multimap.asMap();
814 }
815
816 /**
817 * Returns a multimap view of the specified map. The multimap is backed by the
818 * map, so changes to the map are reflected in the multimap, and vice versa.
819 * If the map is modified while an iteration over one of the multimap's
820 * collection views is in progress (except through the iterator's own {@code
821 * remove} operation, or through the {@code setValue} operation on a map entry
822 * returned by the iterator), the results of the iteration are undefined.
823 *
824 * <p>The multimap supports mapping removal, which removes the corresponding
825 * mapping from the map. It does not support any operations which might add
826 * mappings, such as {@code put}, {@code putAll} or {@code replaceValues}.
827 *
828 * <p>The returned multimap will be serializable if the specified map is
829 * serializable.
830 *
831 * @param map the backing map for the returned multimap view
832 */
833 public static <K, V> SetMultimap<K, V> forMap(Map<K, V> map) {
834 return new MapMultimap<K, V>(map);
835 }
836
837 /** @see Multimaps#forMap */
838 private static class MapMultimap<K, V>
839 extends AbstractMultimap<K, V> implements SetMultimap<K, V>, Serializable {
840 final Map<K, V> map;
841
842 MapMultimap(Map<K, V> map) {
843 this.map = checkNotNull(map);
844 }
845
846 @Override
847 public int size() {
848 return map.size();
849 }
850
851 @Override
852 public boolean containsKey(Object key) {
853 return map.containsKey(key);
854 }
855
856 @Override
857 public boolean containsValue(Object value) {
858 return map.containsValue(value);
859 }
860
861 @Override
862 public boolean containsEntry(Object key, Object value) {
863 return map.entrySet().contains(Maps.immutableEntry(key, value));
864 }
865
866 @Override
867 public Set<V> get(final K key) {
868 return new Sets.ImprovedAbstractSet<V>() {
869 @Override public Iterator<V> iterator() {
870 return new Iterator<V>() {
871 int i;
872
873 @Override
874 public boolean hasNext() {
875 return (i == 0) && map.containsKey(key);
876 }
877
878 @Override
879 public V next() {
880 if (!hasNext()) {
881 throw new NoSuchElementException();
882 }
883 i++;
884 return map.get(key);
885 }
886
887 @Override
888 public void remove() {
889 checkRemove(i == 1);
890 i = -1;
891 map.remove(key);
892 }
893 };
894 }
895
896 @Override public int size() {
897 return map.containsKey(key) ? 1 : 0;
898 }
899 };
900 }
901
902 @Override
903 public boolean put(K key, V value) {
904 throw new UnsupportedOperationException();
905 }
906
907 @Override
908 public boolean putAll(K key, Iterable<? extends V> values) {
909 throw new UnsupportedOperationException();
910 }
911
912 @Override
913 public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
914 throw new UnsupportedOperationException();
915 }
916
917 @Override
918 public Set<V> replaceValues(K key, Iterable<? extends V> values) {
919 throw new UnsupportedOperationException();
920 }
921
922 @Override
923 public boolean remove(Object key, Object value) {
924 return map.entrySet().remove(Maps.immutableEntry(key, value));
925 }
926
927 @Override
928 public Set<V> removeAll(Object key) {
929 Set<V> values = new HashSet<V>(2);
930 if (!map.containsKey(key)) {
931 return values;
932 }
933 values.add(map.remove(key));
934 return values;
935 }
936
937 @Override
938 public void clear() {
939 map.clear();
940 }
941
942 @Override
943 public Set<K> keySet() {
944 return map.keySet();
945 }
946
947 @Override
948 public Collection<V> values() {
949 return map.values();
950 }
951
952 @Override
953 public Set<Entry<K, V>> entries() {
954 return map.entrySet();
955 }
956
957 @Override
958 Iterator<Entry<K, V>> entryIterator() {
959 return map.entrySet().iterator();
960 }
961
962 @Override
963 Map<K, Collection<V>> createAsMap() {
964 return new AsMap<K, V>(this);
965 }
966
967 @Override public int hashCode() {
968 return map.hashCode();
969 }
970
971 private static final long serialVersionUID = 7845222491160860175L;
972 }
973
974 /**
975 * Returns a view of a multimap where each value is transformed by a function.
976 * All other properties of the multimap, such as iteration order, are left
977 * intact. For example, the code: <pre> {@code
978 *
979 * Multimap<String, Integer> multimap =
980 * ImmutableSetMultimap.of("a", 2, "b", -3, "b", -3, "a", 4, "c", 6);
981 * Function<Integer, String> square = new Function<Integer, String>() {
982 * public String apply(Integer in) {
983 * return Integer.toString(in * in);
984 * }
985 * };
986 * Multimap<String, String> transformed =
987 * Multimaps.transformValues(multimap, square);
988 * System.out.println(transformed);}</pre>
989 *
990 * ... prints {@code {a=[4, 16], b=[9, 9], c=[36]}}.
991 *
992 * <p>Changes in the underlying multimap are reflected in this view.
993 * Conversely, this view supports removal operations, and these are reflected
994 * in the underlying multimap.
995 *
996 * <p>It's acceptable for the underlying multimap to contain null keys, and
997 * even null values provided that the function is capable of accepting null
998 * input. The transformed multimap might contain null values, if the function
999 * sometimes gives a null result.
1000 *
1001 * <p>The returned multimap is not thread-safe or serializable, even if the
1002 * underlying multimap is. The {@code equals} and {@code hashCode} methods
1003 * of the returned multimap are meaningless, since there is not a definition
1004 * of {@code equals} or {@code hashCode} for general collections, and
1005 * {@code get()} will return a general {@code Collection} as opposed to a
1006 * {@code List} or a {@code Set}.
1007 *
1008 * <p>The function is applied lazily, invoked when needed. This is necessary
1009 * for the returned multimap to be a view, but it means that the function will
1010 * be applied many times for bulk operations like
1011 * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
1012 * perform well, {@code function} should be fast. To avoid lazy evaluation
1013 * when the returned multimap doesn't need to be a view, copy the returned
1014 * multimap into a new multimap of your choosing.
1015 *
1016 * @since 7.0
1017 */
1018 public static <K, V1, V2> Multimap<K, V2> transformValues(
1019 Multimap<K, V1> fromMultimap, final Function<? super V1, V2> function) {
1020 checkNotNull(function);
1021 EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function);
1022 return transformEntries(fromMultimap, transformer);
1023 }
1024
1025 /**
1026 * Returns a view of a multimap whose values are derived from the original
1027 * multimap's entries. In contrast to {@link #transformValues}, this method's
1028 * entry-transformation logic may depend on the key as well as the value.
1029 *
1030 * <p>All other properties of the transformed multimap, such as iteration
1031 * order, are left intact. For example, the code: <pre> {@code
1032 *
1033 * SetMultimap<String, Integer> multimap =
1034 * ImmutableSetMultimap.of("a", 1, "a", 4, "b", -6);
1035 * EntryTransformer<String, Integer, String> transformer =
1036 * new EntryTransformer<String, Integer, String>() {
1037 * public String transformEntry(String key, Integer value) {
1038 * return (value >= 0) ? key : "no" + key;
1039 * }
1040 * };
1041 * Multimap<String, String> transformed =
1042 * Multimaps.transformEntries(multimap, transformer);
1043 * System.out.println(transformed);}</pre>
1044 *
1045 * ... prints {@code {a=[a, a], b=[nob]}}.
1046 *
1047 * <p>Changes in the underlying multimap are reflected in this view.
1048 * Conversely, this view supports removal operations, and these are reflected
1049 * in the underlying multimap.
1050 *
1051 * <p>It's acceptable for the underlying multimap to contain null keys and
1052 * null values provided that the transformer is capable of accepting null
1053 * inputs. The transformed multimap might contain null values if the
1054 * transformer sometimes gives a null result.
1055 *
1056 * <p>The returned multimap is not thread-safe or serializable, even if the
1057 * underlying multimap is. The {@code equals} and {@code hashCode} methods
1058 * of the returned multimap are meaningless, since there is not a definition
1059 * of {@code equals} or {@code hashCode} for general collections, and
1060 * {@code get()} will return a general {@code Collection} as opposed to a
1061 * {@code List} or a {@code Set}.
1062 *
1063 * <p>The transformer is applied lazily, invoked when needed. This is
1064 * necessary for the returned multimap to be a view, but it means that the
1065 * transformer will be applied many times for bulk operations like {@link
1066 * Multimap#containsValue} and {@link Object#toString}. For this to perform
1067 * well, {@code transformer} should be fast. To avoid lazy evaluation when the
1068 * returned multimap doesn't need to be a view, copy the returned multimap
1069 * into a new multimap of your choosing.
1070 *
1071 * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
1072 * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
1073 * that {@code k2} is also of type {@code K}. Using an {@code
1074 * EntryTransformer} key type for which this may not hold, such as {@code
1075 * ArrayList}, may risk a {@code ClassCastException} when calling methods on
1076 * the transformed multimap.
1077 *
1078 * @since 7.0
1079 */
1080 public static <K, V1, V2> Multimap<K, V2> transformEntries(
1081 Multimap<K, V1> fromMap,
1082 EntryTransformer<? super K, ? super V1, V2> transformer) {
1083 return new TransformedEntriesMultimap<K, V1, V2>(fromMap, transformer);
1084 }
1085
1086 private static class TransformedEntriesMultimap<K, V1, V2>
1087 extends AbstractMultimap<K, V2> {
1088 final Multimap<K, V1> fromMultimap;
1089 final EntryTransformer<? super K, ? super V1, V2> transformer;
1090
1091 TransformedEntriesMultimap(Multimap<K, V1> fromMultimap,
1092 final EntryTransformer<? super K, ? super V1, V2> transformer) {
1093 this.fromMultimap = checkNotNull(fromMultimap);
1094 this.transformer = checkNotNull(transformer);
1095 }
1096
1097 Collection<V2> transform(K key, Collection<V1> values) {
1098 Function<? super V1, V2> function =
1099 Maps.asValueToValueFunction(transformer, key);
1100 if (values instanceof List) {
1101 return Lists.transform((List<V1>) values, function);
1102 } else {
1103 return Collections2.transform(values, function);
1104 }
1105 }
1106
1107 @Override
1108 Map<K, Collection<V2>> createAsMap() {
1109 return Maps.transformEntries(fromMultimap.asMap(),
1110 new EntryTransformer<K, Collection<V1>, Collection<V2>>() {
1111 @Override public Collection<V2> transformEntry(
1112 K key, Collection<V1> value) {
1113 return transform(key, value);
1114 }
1115 });
1116 }
1117
1118 @Override public void clear() {
1119 fromMultimap.clear();
1120 }
1121
1122 @Override public boolean containsKey(Object key) {
1123 return fromMultimap.containsKey(key);
1124 }
1125
1126 @Override
1127 Iterator<Entry<K, V2>> entryIterator() {
1128 return Iterators.transform(fromMultimap.entries().iterator(),
1129 Maps.<K, V1, V2>asEntryToEntryFunction(transformer));
1130 }
1131
1132 @Override public Collection<V2> get(final K key) {
1133 return transform(key, fromMultimap.get(key));
1134 }
1135
1136 @Override public boolean isEmpty() {
1137 return fromMultimap.isEmpty();
1138 }
1139
1140 @Override public Set<K> keySet() {
1141 return fromMultimap.keySet();
1142 }
1143
1144 @Override public Multiset<K> keys() {
1145 return fromMultimap.keys();
1146 }
1147
1148 @Override public boolean put(K key, V2 value) {
1149 throw new UnsupportedOperationException();
1150 }
1151
1152 @Override public boolean putAll(K key, Iterable<? extends V2> values) {
1153 throw new UnsupportedOperationException();
1154 }
1155
1156 @Override public boolean putAll(
1157 Multimap<? extends K, ? extends V2> multimap) {
1158 throw new UnsupportedOperationException();
1159 }
1160
1161 @SuppressWarnings("unchecked")
1162 @Override public boolean remove(Object key, Object value) {
1163 return get((K) key).remove(value);
1164 }
1165
1166 @SuppressWarnings("unchecked")
1167 @Override public Collection<V2> removeAll(Object key) {
1168 return transform((K) key, fromMultimap.removeAll(key));
1169 }
1170
1171 @Override public Collection<V2> replaceValues(
1172 K key, Iterable<? extends V2> values) {
1173 throw new UnsupportedOperationException();
1174 }
1175
1176 @Override public int size() {
1177 return fromMultimap.size();
1178 }
1179
1180 @Override
1181 Collection<V2> createValues() {
1182 return Collections2.transform(
1183 fromMultimap.entries(), Maps.<K, V1, V2>asEntryToValueFunction(transformer));
1184 }
1185 }
1186
1187 /**
1188 * Returns a view of a {@code ListMultimap} where each value is transformed by
1189 * a function. All other properties of the multimap, such as iteration order,
1190 * are left intact. For example, the code: <pre> {@code
1191 *
1192 * ListMultimap<String, Integer> multimap
1193 * = ImmutableListMultimap.of("a", 4, "a", 16, "b", 9);
1194 * Function<Integer, Double> sqrt =
1195 * new Function<Integer, Double>() {
1196 * public Double apply(Integer in) {
1197 * return Math.sqrt((int) in);
1198 * }
1199 * };
1200 * ListMultimap<String, Double> transformed = Multimaps.transformValues(map,
1201 * sqrt);
1202 * System.out.println(transformed);}</pre>
1203 *
1204 * ... prints {@code {a=[2.0, 4.0], b=[3.0]}}.
1205 *
1206 * <p>Changes in the underlying multimap are reflected in this view.
1207 * Conversely, this view supports removal operations, and these are reflected
1208 * in the underlying multimap.
1209 *
1210 * <p>It's acceptable for the underlying multimap to contain null keys, and
1211 * even null values provided that the function is capable of accepting null
1212 * input. The transformed multimap might contain null values, if the function
1213 * sometimes gives a null result.
1214 *
1215 * <p>The returned multimap is not thread-safe or serializable, even if the
1216 * underlying multimap is.
1217 *
1218 * <p>The function is applied lazily, invoked when needed. This is necessary
1219 * for the returned multimap to be a view, but it means that the function will
1220 * be applied many times for bulk operations like
1221 * {@link Multimap#containsValue} and {@code Multimap.toString()}. For this to
1222 * perform well, {@code function} should be fast. To avoid lazy evaluation
1223 * when the returned multimap doesn't need to be a view, copy the returned
1224 * multimap into a new multimap of your choosing.
1225 *
1226 * @since 7.0
1227 */
1228 public static <K, V1, V2> ListMultimap<K, V2> transformValues(
1229 ListMultimap<K, V1> fromMultimap,
1230 final Function<? super V1, V2> function) {
1231 checkNotNull(function);
1232 EntryTransformer<K, V1, V2> transformer = Maps.asEntryTransformer(function);
1233 return transformEntries(fromMultimap, transformer);
1234 }
1235
1236 /**
1237 * Returns a view of a {@code ListMultimap} whose values are derived from the
1238 * original multimap's entries. In contrast to
1239 * {@link #transformValues(ListMultimap, Function)}, this method's
1240 * entry-transformation logic may depend on the key as well as the value.
1241 *
1242 * <p>All other properties of the transformed multimap, such as iteration
1243 * order, are left intact. For example, the code: <pre> {@code
1244 *
1245 * Multimap<String, Integer> multimap =
1246 * ImmutableMultimap.of("a", 1, "a", 4, "b", 6);
1247 * EntryTransformer<String, Integer, String> transformer =
1248 * new EntryTransformer<String, Integer, String>() {
1249 * public String transformEntry(String key, Integer value) {
1250 * return key + value;
1251 * }
1252 * };
1253 * Multimap<String, String> transformed =
1254 * Multimaps.transformEntries(multimap, transformer);
1255 * System.out.println(transformed);}</pre>
1256 *
1257 * ... prints {@code {"a"=["a1", "a4"], "b"=["b6"]}}.
1258 *
1259 * <p>Changes in the underlying multimap are reflected in this view.
1260 * Conversely, this view supports removal operations, and these are reflected
1261 * in the underlying multimap.
1262 *
1263 * <p>It's acceptable for the underlying multimap to contain null keys and
1264 * null values provided that the transformer is capable of accepting null
1265 * inputs. The transformed multimap might contain null values if the
1266 * transformer sometimes gives a null result.
1267 *
1268 * <p>The returned multimap is not thread-safe or serializable, even if the
1269 * underlying multimap is.
1270 *
1271 * <p>The transformer is applied lazily, invoked when needed. This is
1272 * necessary for the returned multimap to be a view, but it means that the
1273 * transformer will be applied many times for bulk operations like {@link
1274 * Multimap#containsValue} and {@link Object#toString}. For this to perform
1275 * well, {@code transformer} should be fast. To avoid lazy evaluation when the
1276 * returned multimap doesn't need to be a view, copy the returned multimap
1277 * into a new multimap of your choosing.
1278 *
1279 * <p><b>Warning:</b> This method assumes that for any instance {@code k} of
1280 * {@code EntryTransformer} key type {@code K}, {@code k.equals(k2)} implies
1281 * that {@code k2} is also of type {@code K}. Using an {@code
1282 * EntryTransformer} key type for which this may not hold, such as {@code
1283 * ArrayList}, may risk a {@code ClassCastException} when calling methods on
1284 * the transformed multimap.
1285 *
1286 * @since 7.0
1287 */
1288 public static <K, V1, V2> ListMultimap<K, V2> transformEntries(
1289 ListMultimap<K, V1> fromMap,
1290 EntryTransformer<? super K, ? super V1, V2> transformer) {
1291 return new TransformedEntriesListMultimap<K, V1, V2>(fromMap, transformer);
1292 }
1293
1294 private static final class TransformedEntriesListMultimap<K, V1, V2>
1295 extends TransformedEntriesMultimap<K, V1, V2>
1296 implements ListMultimap<K, V2> {
1297
1298 TransformedEntriesListMultimap(ListMultimap<K, V1> fromMultimap,
1299 EntryTransformer<? super K, ? super V1, V2> transformer) {
1300 super(fromMultimap, transformer);
1301 }
1302
1303 @Override List<V2> transform(K key, Collection<V1> values) {
1304 return Lists.transform((List<V1>) values, Maps.asValueToValueFunction(transformer, key));
1305 }
1306
1307 @Override public List<V2> get(K key) {
1308 return transform(key, fromMultimap.get(key));
1309 }
1310
1311 @SuppressWarnings("unchecked")
1312 @Override public List<V2> removeAll(Object key) {
1313 return transform((K) key, fromMultimap.removeAll(key));
1314 }
1315
1316 @Override public List<V2> replaceValues(
1317 K key, Iterable<? extends V2> values) {
1318 throw new UnsupportedOperationException();
1319 }
1320 }
1321
1322 /**
1323 * Creates an index {@code ImmutableListMultimap} that contains the results of
1324 * applying a specified function to each item in an {@code Iterable} of
1325 * values. Each value will be stored as a value in the resulting multimap,
1326 * yielding a multimap with the same size as the input iterable. The key used
1327 * to store that value in the multimap will be the result of calling the
1328 * function on that value. The resulting multimap is created as an immutable
1329 * snapshot. In the returned multimap, keys appear in the order they are first
1330 * encountered, and the values corresponding to each key appear in the same
1331 * order as they are encountered.
1332 *
1333 * <p>For example, <pre> {@code
1334 *
1335 * List<String> badGuys =
1336 * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
1337 * Function<String, Integer> stringLengthFunction = ...;
1338 * Multimap<Integer, String> index =
1339 * Multimaps.index(badGuys, stringLengthFunction);
1340 * System.out.println(index);}</pre>
1341 *
1342 * <p>prints <pre> {@code
1343 *
1344 * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre>
1345 *
1346 * <p>The returned multimap is serializable if its keys and values are all
1347 * serializable.
1348 *
1349 * @param values the values to use when constructing the {@code
1350 * ImmutableListMultimap}
1351 * @param keyFunction the function used to produce the key for each value
1352 * @return {@code ImmutableListMultimap} mapping the result of evaluating the
1353 * function {@code keyFunction} on each value in the input collection to
1354 * that value
1355 * @throws NullPointerException if any of the following cases is true:
1356 * <ul>
1357 * <li>{@code values} is null
1358 * <li>{@code keyFunction} is null
1359 * <li>An element in {@code values} is null
1360 * <li>{@code keyFunction} returns {@code null} for any element of {@code
1361 * values}
1362 * </ul>
1363 */
1364 public static <K, V> ImmutableListMultimap<K, V> index(
1365 Iterable<V> values, Function<? super V, K> keyFunction) {
1366 return index(values.iterator(), keyFunction);
1367 }
1368
1369 /**
1370 * Creates an index {@code ImmutableListMultimap} that contains the results of
1371 * applying a specified function to each item in an {@code Iterator} of
1372 * values. Each value will be stored as a value in the resulting multimap,
1373 * yielding a multimap with the same size as the input iterator. The key used
1374 * to store that value in the multimap will be the result of calling the
1375 * function on that value. The resulting multimap is created as an immutable
1376 * snapshot. In the returned multimap, keys appear in the order they are first
1377 * encountered, and the values corresponding to each key appear in the same
1378 * order as they are encountered.
1379 *
1380 * <p>For example, <pre> {@code
1381 *
1382 * List<String> badGuys =
1383 * Arrays.asList("Inky", "Blinky", "Pinky", "Pinky", "Clyde");
1384 * Function<String, Integer> stringLengthFunction = ...;
1385 * Multimap<Integer, String> index =
1386 * Multimaps.index(badGuys.iterator(), stringLengthFunction);
1387 * System.out.println(index);}</pre>
1388 *
1389 * <p>prints <pre> {@code
1390 *
1391 * {4=[Inky], 6=[Blinky], 5=[Pinky, Pinky, Clyde]}}</pre>
1392 *
1393 * <p>The returned multimap is serializable if its keys and values are all
1394 * serializable.
1395 *
1396 * @param values the values to use when constructing the {@code
1397 * ImmutableListMultimap}
1398 * @param keyFunction the function used to produce the key for each value
1399 * @return {@code ImmutableListMultimap} mapping the result of evaluating the
1400 * function {@code keyFunction} on each value in the input collection to
1401 * that value
1402 * @throws NullPointerException if any of the following cases is true:
1403 * <ul>
1404 * <li>{@code values} is null
1405 * <li>{@code keyFunction} is null
1406 * <li>An element in {@code values} is null
1407 * <li>{@code keyFunction} returns {@code null} for any element of {@code
1408 * values}
1409 * </ul>
1410 * @since 10.0
1411 */
1412 public static <K, V> ImmutableListMultimap<K, V> index(
1413 Iterator<V> values, Function<? super V, K> keyFunction) {
1414 checkNotNull(keyFunction);
1415 ImmutableListMultimap.Builder<K, V> builder
1416 = ImmutableListMultimap.builder();
1417 while (values.hasNext()) {
1418 V value = values.next();
1419 checkNotNull(value, values);
1420 builder.put(keyFunction.apply(value), value);
1421 }
1422 return builder.build();
1423 }
1424
1425 static class Keys<K, V> extends AbstractMultiset<K> {
1426 final Multimap<K, V> multimap;
1427
1428 Keys(Multimap<K, V> multimap) {
1429 this.multimap = multimap;
1430 }
1431
1432 @Override Iterator<Multiset.Entry<K>> entryIterator() {
1433 return new TransformedIterator<Map.Entry<K, Collection<V>>, Multiset.Entry<K>>(
1434 multimap.asMap().entrySet().iterator()) {
1435 @Override
1436 Multiset.Entry<K> transform(
1437 final Map.Entry<K, Collection<V>> backingEntry) {
1438 return new Multisets.AbstractEntry<K>() {
1439 @Override
1440 public K getElement() {
1441 return backingEntry.getKey();
1442 }
1443
1444 @Override
1445 public int getCount() {
1446 return backingEntry.getValue().size();
1447 }
1448 };
1449 }
1450 };
1451 }
1452
1453 @Override int distinctElements() {
1454 return multimap.asMap().size();
1455 }
1456
1457 @Override Set<Multiset.Entry<K>> createEntrySet() {
1458 return new KeysEntrySet();
1459 }
1460
1461 class KeysEntrySet extends Multisets.EntrySet<K> {
1462 @Override Multiset<K> multiset() {
1463 return Keys.this;
1464 }
1465
1466 @Override public Iterator<Multiset.Entry<K>> iterator() {
1467 return entryIterator();
1468 }
1469
1470 @Override public int size() {
1471 return distinctElements();
1472 }
1473
1474 @Override public boolean isEmpty() {
1475 return multimap.isEmpty();
1476 }
1477
1478 @Override public boolean contains(@Nullable Object o) {
1479 if (o instanceof Multiset.Entry) {
1480 Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
1481 Collection<V> collection = multimap.asMap().get(entry.getElement());
1482 return collection != null && collection.size() == entry.getCount();
1483 }
1484 return false;
1485 }
1486
1487 @Override public boolean remove(@Nullable Object o) {
1488 if (o instanceof Multiset.Entry) {
1489 Multiset.Entry<?> entry = (Multiset.Entry<?>) o;
1490 Collection<V> collection = multimap.asMap().get(entry.getElement());
1491 if (collection != null && collection.size() == entry.getCount()) {
1492 collection.clear();
1493 return true;
1494 }
1495 }
1496 return false;
1497 }
1498 }
1499
1500 @Override public boolean contains(@Nullable Object element) {
1501 return multimap.containsKey(element);
1502 }
1503
1504 @Override public Iterator<K> iterator() {
1505 return Maps.keyIterator(multimap.entries().iterator());
1506 }
1507
1508 @Override public int count(@Nullable Object element) {
1509 Collection<V> values = Maps.safeGet(multimap.asMap(), element);
1510 return (values == null) ? 0 : values.size();
1511 }
1512
1513 @Override public int remove(@Nullable Object element, int occurrences) {
1514 checkNonnegative(occurrences, "occurrences");
1515 if (occurrences == 0) {
1516 return count(element);
1517 }
1518
1519 Collection<V> values = Maps.safeGet(multimap.asMap(), element);
1520
1521 if (values == null) {
1522 return 0;
1523 }
1524
1525 int oldCount = values.size();
1526 if (occurrences >= oldCount) {
1527 values.clear();
1528 } else {
1529 Iterator<V> iterator = values.iterator();
1530 for (int i = 0; i < occurrences; i++) {
1531 iterator.next();
1532 iterator.remove();
1533 }
1534 }
1535 return oldCount;
1536 }
1537
1538 @Override public void clear() {
1539 multimap.clear();
1540 }
1541
1542 @Override public Set<K> elementSet() {
1543 return multimap.keySet();
1544 }
1545 }
1546
1547 /**
1548 * A skeleton implementation of {@link Multimap#entries()}.
1549 */
1550 abstract static class Entries<K, V> extends
1551 AbstractCollection<Map.Entry<K, V>> {
1552 abstract Multimap<K, V> multimap();
1553
1554 @Override public int size() {
1555 return multimap().size();
1556 }
1557
1558 @Override public boolean contains(@Nullable Object o) {
1559 if (o instanceof Map.Entry) {
1560 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1561 return multimap().containsEntry(entry.getKey(), entry.getValue());
1562 }
1563 return false;
1564 }
1565
1566 @Override public boolean remove(@Nullable Object o) {
1567 if (o instanceof Map.Entry) {
1568 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1569 return multimap().remove(entry.getKey(), entry.getValue());
1570 }
1571 return false;
1572 }
1573
1574 @Override public void clear() {
1575 multimap().clear();
1576 }
1577 }
1578
1579 /**
1580 * A skeleton implementation of {@link Multimap#asMap()}.
1581 */
1582 static final class AsMap<K, V> extends
1583 Maps.ImprovedAbstractMap<K, Collection<V>> {
1584 private final Multimap<K, V> multimap;
1585
1586 AsMap(Multimap<K, V> multimap) {
1587 this.multimap = checkNotNull(multimap);
1588 }
1589
1590 @Override public int size() {
1591 return multimap.keySet().size();
1592 }
1593
1594 @Override protected Set<Entry<K, Collection<V>>> createEntrySet() {
1595 return new EntrySet();
1596 }
1597
1598 void removeValuesForKey(Object key) {
1599 multimap.keySet().remove(key);
1600 }
1601
1602 class EntrySet extends Maps.EntrySet<K, Collection<V>> {
1603 @Override Map<K, Collection<V>> map() {
1604 return AsMap.this;
1605 }
1606
1607 @Override public Iterator<Entry<K, Collection<V>>> iterator() {
1608 return Maps.asMapEntryIterator(multimap.keySet(), new Function<K, Collection<V>>() {
1609 @Override
1610 public Collection<V> apply(K key) {
1611 return multimap.get(key);
1612 }
1613 });
1614 }
1615
1616 @Override public boolean remove(Object o) {
1617 if (!contains(o)) {
1618 return false;
1619 }
1620 Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
1621 removeValuesForKey(entry.getKey());
1622 return true;
1623 }
1624 }
1625
1626 @SuppressWarnings("unchecked")
1627 @Override public Collection<V> get(Object key) {
1628 return containsKey(key) ? multimap.get((K) key) : null;
1629 }
1630
1631 @Override public Collection<V> remove(Object key) {
1632 return containsKey(key) ? multimap.removeAll(key) : null;
1633 }
1634
1635 @Override public Set<K> keySet() {
1636 return multimap.keySet();
1637 }
1638
1639 @Override public boolean isEmpty() {
1640 return multimap.isEmpty();
1641 }
1642
1643 @Override public boolean containsKey(Object key) {
1644 return multimap.containsKey(key);
1645 }
1646
1647 @Override public void clear() {
1648 multimap.clear();
1649 }
1650 }
1651
1652 /**
1653 * Returns a multimap containing the mappings in {@code unfiltered} whose keys
1654 * satisfy a predicate. The returned multimap is a live view of
1655 * {@code unfiltered}; changes to one affect the other.
1656 *
1657 * <p>The resulting multimap's views have iterators that don't support
1658 * {@code remove()}, but all other methods are supported by the multimap and
1659 * its views. When adding a key that doesn't satisfy the predicate, the
1660 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1661 * methods throw an {@link IllegalArgumentException}.
1662 *
1663 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1664 * the filtered multimap or its views, only mappings whose keys satisfy the
1665 * filter will be removed from the underlying multimap.
1666 *
1667 * <p>The returned multimap isn't threadsafe or serializable, even if
1668 * {@code unfiltered} is.
1669 *
1670 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1671 * across every key/value mapping in the underlying multimap and determine
1672 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1673 * faster to copy the filtered multimap and use the copy.
1674 *
1675 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>,
1676 * as documented at {@link Predicate#apply}. Do not provide a predicate such
1677 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent
1678 * with equals.
1679 *
1680 * @since 11.0
1681 */
1682 public static <K, V> Multimap<K, V> filterKeys(
1683 Multimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1684 if (unfiltered instanceof SetMultimap) {
1685 return filterKeys((SetMultimap<K, V>) unfiltered, keyPredicate);
1686 } else if (unfiltered instanceof ListMultimap) {
1687 return filterKeys((ListMultimap<K, V>) unfiltered, keyPredicate);
1688 } else if (unfiltered instanceof FilteredKeyMultimap) {
1689 FilteredKeyMultimap<K, V> prev = (FilteredKeyMultimap<K, V>) unfiltered;
1690 return new FilteredKeyMultimap<K, V>(prev.unfiltered,
1691 Predicates.and(prev.keyPredicate, keyPredicate));
1692 } else if (unfiltered instanceof FilteredMultimap) {
1693 FilteredMultimap<K, V> prev = (FilteredMultimap<K, V>) unfiltered;
1694 return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate));
1695 } else {
1696 return new FilteredKeyMultimap<K, V>(unfiltered, keyPredicate);
1697 }
1698 }
1699
1700 /**
1701 * Returns a multimap containing the mappings in {@code unfiltered} whose keys
1702 * satisfy a predicate. The returned multimap is a live view of
1703 * {@code unfiltered}; changes to one affect the other.
1704 *
1705 * <p>The resulting multimap's views have iterators that don't support
1706 * {@code remove()}, but all other methods are supported by the multimap and
1707 * its views. When adding a key that doesn't satisfy the predicate, the
1708 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1709 * methods throw an {@link IllegalArgumentException}.
1710 *
1711 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1712 * the filtered multimap or its views, only mappings whose keys satisfy the
1713 * filter will be removed from the underlying multimap.
1714 *
1715 * <p>The returned multimap isn't threadsafe or serializable, even if
1716 * {@code unfiltered} is.
1717 *
1718 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1719 * across every key/value mapping in the underlying multimap and determine
1720 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1721 * faster to copy the filtered multimap and use the copy.
1722 *
1723 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>,
1724 * as documented at {@link Predicate#apply}. Do not provide a predicate such
1725 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent
1726 * with equals.
1727 *
1728 * @since 14.0
1729 */
1730 public static <K, V> SetMultimap<K, V> filterKeys(
1731 SetMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1732 if (unfiltered instanceof FilteredKeySetMultimap) {
1733 FilteredKeySetMultimap<K, V> prev = (FilteredKeySetMultimap<K, V>) unfiltered;
1734 return new FilteredKeySetMultimap<K, V>(prev.unfiltered(),
1735 Predicates.and(prev.keyPredicate, keyPredicate));
1736 } else if (unfiltered instanceof FilteredSetMultimap) {
1737 FilteredSetMultimap<K, V> prev = (FilteredSetMultimap<K, V>) unfiltered;
1738 return filterFiltered(prev, Maps.<K>keyPredicateOnEntries(keyPredicate));
1739 } else {
1740 return new FilteredKeySetMultimap<K, V>(unfiltered, keyPredicate);
1741 }
1742 }
1743
1744 /**
1745 * Returns a multimap containing the mappings in {@code unfiltered} whose keys
1746 * satisfy a predicate. The returned multimap is a live view of
1747 * {@code unfiltered}; changes to one affect the other.
1748 *
1749 * <p>The resulting multimap's views have iterators that don't support
1750 * {@code remove()}, but all other methods are supported by the multimap and
1751 * its views. When adding a key that doesn't satisfy the predicate, the
1752 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1753 * methods throw an {@link IllegalArgumentException}.
1754 *
1755 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1756 * the filtered multimap or its views, only mappings whose keys satisfy the
1757 * filter will be removed from the underlying multimap.
1758 *
1759 * <p>The returned multimap isn't threadsafe or serializable, even if
1760 * {@code unfiltered} is.
1761 *
1762 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1763 * across every key/value mapping in the underlying multimap and determine
1764 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1765 * faster to copy the filtered multimap and use the copy.
1766 *
1767 * <p><b>Warning:</b> {@code keyPredicate} must be <i>consistent with equals</i>,
1768 * as documented at {@link Predicate#apply}. Do not provide a predicate such
1769 * as {@code Predicates.instanceOf(ArrayList.class)}, which is inconsistent
1770 * with equals.
1771 *
1772 * @since 14.0
1773 */
1774 public static <K, V> ListMultimap<K, V> filterKeys(
1775 ListMultimap<K, V> unfiltered, final Predicate<? super K> keyPredicate) {
1776 if (unfiltered instanceof FilteredKeyListMultimap) {
1777 FilteredKeyListMultimap<K, V> prev = (FilteredKeyListMultimap<K, V>) unfiltered;
1778 return new FilteredKeyListMultimap<K, V>(prev.unfiltered(),
1779 Predicates.and(prev.keyPredicate, keyPredicate));
1780 } else {
1781 return new FilteredKeyListMultimap<K, V>(unfiltered, keyPredicate);
1782 }
1783 }
1784
1785 /**
1786 * Returns a multimap containing the mappings in {@code unfiltered} whose values
1787 * satisfy a predicate. The returned multimap is a live view of
1788 * {@code unfiltered}; changes to one affect the other.
1789 *
1790 * <p>The resulting multimap's views have iterators that don't support
1791 * {@code remove()}, but all other methods are supported by the multimap and
1792 * its views. When adding a value that doesn't satisfy the predicate, the
1793 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1794 * methods throw an {@link IllegalArgumentException}.
1795 *
1796 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1797 * the filtered multimap or its views, only mappings whose value satisfy the
1798 * filter will be removed from the underlying multimap.
1799 *
1800 * <p>The returned multimap isn't threadsafe or serializable, even if
1801 * {@code unfiltered} is.
1802 *
1803 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1804 * across every key/value mapping in the underlying multimap and determine
1805 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1806 * faster to copy the filtered multimap and use the copy.
1807 *
1808 * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
1809 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
1810 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
1811 * inconsistent with equals.
1812 *
1813 * @since 11.0
1814 */
1815 public static <K, V> Multimap<K, V> filterValues(
1816 Multimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
1817 return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
1818 }
1819
1820 /**
1821 * Returns a multimap containing the mappings in {@code unfiltered} whose values
1822 * satisfy a predicate. The returned multimap is a live view of
1823 * {@code unfiltered}; changes to one affect the other.
1824 *
1825 * <p>The resulting multimap's views have iterators that don't support
1826 * {@code remove()}, but all other methods are supported by the multimap and
1827 * its views. When adding a value that doesn't satisfy the predicate, the
1828 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1829 * methods throw an {@link IllegalArgumentException}.
1830 *
1831 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1832 * the filtered multimap or its views, only mappings whose value satisfy the
1833 * filter will be removed from the underlying multimap.
1834 *
1835 * <p>The returned multimap isn't threadsafe or serializable, even if
1836 * {@code unfiltered} is.
1837 *
1838 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1839 * across every key/value mapping in the underlying multimap and determine
1840 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1841 * faster to copy the filtered multimap and use the copy.
1842 *
1843 * <p><b>Warning:</b> {@code valuePredicate} must be <i>consistent with
1844 * equals</i>, as documented at {@link Predicate#apply}. Do not provide a
1845 * predicate such as {@code Predicates.instanceOf(ArrayList.class)}, which is
1846 * inconsistent with equals.
1847 *
1848 * @since 14.0
1849 */
1850 public static <K, V> SetMultimap<K, V> filterValues(
1851 SetMultimap<K, V> unfiltered, final Predicate<? super V> valuePredicate) {
1852 return filterEntries(unfiltered, Maps.<V>valuePredicateOnEntries(valuePredicate));
1853 }
1854
1855 /**
1856 * Returns a multimap containing the mappings in {@code unfiltered} that
1857 * satisfy a predicate. The returned multimap is a live view of
1858 * {@code unfiltered}; changes to one affect the other.
1859 *
1860 * <p>The resulting multimap's views have iterators that don't support
1861 * {@code remove()}, but all other methods are supported by the multimap and
1862 * its views. When adding a key/value pair that doesn't satisfy the predicate,
1863 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1864 * methods throw an {@link IllegalArgumentException}.
1865 *
1866 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1867 * the filtered multimap or its views, only mappings whose keys satisfy the
1868 * filter will be removed from the underlying multimap.
1869 *
1870 * <p>The returned multimap isn't threadsafe or serializable, even if
1871 * {@code unfiltered} is.
1872 *
1873 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1874 * across every key/value mapping in the underlying multimap and determine
1875 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1876 * faster to copy the filtered multimap and use the copy.
1877 *
1878 * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
1879 * equals</i>, as documented at {@link Predicate#apply}.
1880 *
1881 * @since 11.0
1882 */
1883 public static <K, V> Multimap<K, V> filterEntries(
1884 Multimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
1885 checkNotNull(entryPredicate);
1886 if (unfiltered instanceof SetMultimap) {
1887 return filterEntries((SetMultimap<K, V>) unfiltered, entryPredicate);
1888 }
1889 return (unfiltered instanceof FilteredMultimap)
1890 ? filterFiltered((FilteredMultimap<K, V>) unfiltered, entryPredicate)
1891 : new FilteredEntryMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
1892 }
1893
1894 /**
1895 * Returns a multimap containing the mappings in {@code unfiltered} that
1896 * satisfy a predicate. The returned multimap is a live view of
1897 * {@code unfiltered}; changes to one affect the other.
1898 *
1899 * <p>The resulting multimap's views have iterators that don't support
1900 * {@code remove()}, but all other methods are supported by the multimap and
1901 * its views. When adding a key/value pair that doesn't satisfy the predicate,
1902 * multimap's {@code put()}, {@code putAll()}, and {@code replaceValues()}
1903 * methods throw an {@link IllegalArgumentException}.
1904 *
1905 * <p>When methods such as {@code removeAll()} and {@code clear()} are called on
1906 * the filtered multimap or its views, only mappings whose keys satisfy the
1907 * filter will be removed from the underlying multimap.
1908 *
1909 * <p>The returned multimap isn't threadsafe or serializable, even if
1910 * {@code unfiltered} is.
1911 *
1912 * <p>Many of the filtered multimap's methods, such as {@code size()}, iterate
1913 * across every key/value mapping in the underlying multimap and determine
1914 * which satisfy the filter. When a live view is <i>not</i> needed, it may be
1915 * faster to copy the filtered multimap and use the copy.
1916 *
1917 * <p><b>Warning:</b> {@code entryPredicate} must be <i>consistent with
1918 * equals</i>, as documented at {@link Predicate#apply}.
1919 *
1920 * @since 14.0
1921 */
1922 public static <K, V> SetMultimap<K, V> filterEntries(
1923 SetMultimap<K, V> unfiltered, Predicate<? super Entry<K, V>> entryPredicate) {
1924 checkNotNull(entryPredicate);
1925 return (unfiltered instanceof FilteredSetMultimap)
1926 ? filterFiltered((FilteredSetMultimap<K, V>) unfiltered, entryPredicate)
1927 : new FilteredEntrySetMultimap<K, V>(checkNotNull(unfiltered), entryPredicate);
1928 }
1929
1930 /**
1931 * Support removal operations when filtering a filtered multimap. Since a
1932 * filtered multimap has iterators that don't support remove, passing one to
1933 * the FilteredEntryMultimap constructor would lead to a multimap whose removal
1934 * operations would fail. This method combines the predicates to avoid that
1935 * problem.
1936 */
1937 private static <K, V> Multimap<K, V> filterFiltered(FilteredMultimap<K, V> multimap,
1938 Predicate<? super Entry<K, V>> entryPredicate) {
1939 Predicate<Entry<K, V>> predicate
1940 = Predicates.and(multimap.entryPredicate(), entryPredicate);
1941 return new FilteredEntryMultimap<K, V>(multimap.unfiltered(), predicate);
1942 }
1943
1944 /**
1945 * Support removal operations when filtering a filtered multimap. Since a filtered multimap has
1946 * iterators that don't support remove, passing one to the FilteredEntryMultimap constructor would
1947 * lead to a multimap whose removal operations would fail. This method combines the predicates to
1948 * avoid that problem.
1949 */
1950 private static <K, V> SetMultimap<K, V> filterFiltered(
1951 FilteredSetMultimap<K, V> multimap,
1952 Predicate<? super Entry<K, V>> entryPredicate) {
1953 Predicate<Entry<K, V>> predicate
1954 = Predicates.and(multimap.entryPredicate(), entryPredicate);
1955 return new FilteredEntrySetMultimap<K, V>(multimap.unfiltered(), predicate);
1956 }
1957
1958 static boolean equalsImpl(Multimap<?, ?> multimap, @Nullable Object object) {
1959 if (object == multimap) {
1960 return true;
1961 }
1962 if (object instanceof Multimap) {
1963 Multimap<?, ?> that = (Multimap<?, ?>) object;
1964 return multimap.asMap().equals(that.asMap());
1965 }
1966 return false;
1967 }
1968
1969 // TODO(jlevy): Create methods that filter a SortedSetMultimap.
1970 }
1971